package kr.inani.android.view.adapter;

import java.util.List;

import kr.inani.R;
import kr.inani.android.MainActivity;
import kr.inani.android.search.BookItem;
import kr.inani.android.search.BookShelf;
import kr.inani.android.view.AddBookView;
import kr.inani.android.view.BookView;
import kr.inani.android.view.CustomHorizontalScrollView;
import kr.inani.android.view.CustomLinearLayout;
import kr.inani.android.view.IconTextView;
import kr.inani.android.view.drag.BookDragInfo;
import kr.inani.android.view.drag.DragController;
import kr.inani.android.view.drag.DragLayer;
import kr.inani.android.view.drag.DragSource;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;

public class BookShelfsAdapter extends ItemsAdapter<BookShelf> implements View.OnLongClickListener, DragSource
{
	private static final int	DEFAULT_BOOK_SIZE_PER_SHELF	= 20;
	private final DragController mDragController;   // Object that sends out drag-drop events while a view is being moved.
	private DragLayer mDragLayer;             // The ViewGroup that supports drag-drop.
	private RememberBookItem rememberBookItem;
	
	public BookShelfsAdapter(Context context, int layout, List<BookShelf> list)
	{
		super(context, layout, list);
		mDragController = new DragController(context);
		setupViews(context);
	}

	@Override
	public View getView(final int position, View convertView, ViewGroup parent)
	{
		if (convertView == null) {
			convertView = inflater.inflate(layout, parent, false);
			convertView.setTag(newHolder(convertView));
		}
		BookShelfViewHolder holder = (BookShelfViewHolder) convertView.getTag();
		holder.position = position;
		holder.bookShelfLayout.setBookShelf(getItem(position));
		holder.shelfNameTextView.setText(getItem(position).getShelfName());
		
		final int bookCount = getItem(position).getBookCount();
		addViewAsMuchAs(bookCount, holder);
		final BookShelf bookShelf = getItem(position);
		initView(holder, bookShelf);
		setupViewWithBookItem(holder, bookCount, bookShelf);

		return convertView;
	}
	
	@Override
	public boolean onLongClick(View v) {
	    if (!v.isInTouchMode()) {
	       return false;
	    }
		BookItem bookItem = ((BookView) v).getBookItem();
		if(bookItem==null) {
			return false;
		}
		BookShelf bookShelf = findBookShelfWith(bookItem.getShelfName());
		int removeIndex = bookShelf.remove(bookItem);
		if(bookShelf!=null&&removeIndex!=-1) {
			rememberBookItem = new RememberBookItem(bookItem, removeIndex, bookItem.getShelfName());
			return startDrag (v);
		}
		return false;
	}

	@Override
	public void setDragController(DragController dragger) {}

	@SuppressWarnings("unchecked")
	@Override
	public synchronized void onDropCompleted(View target, boolean success) 
	{
		if(!success) {
			if(rememberBookItem!=null) {
				BookShelf bookShelf = findBookShelfWith(rememberBookItem.bookItem.getShelfName());
				if(bookShelf!=null) {
					bookShelf.insertBook(rememberBookItem.bookItem, rememberBookItem.index);
				}
				rememberBookItem = null;
			}
		} else {
			if(rememberBookItem!=null) {
				boolean isSame = rememberBookItem.rememberShelfName==rememberBookItem.bookItem.getShelfName();
				if(isSame) {
					((MainActivity) context).updateBook(findBookShelfWith(rememberBookItem.rememberShelfName).getBookItemList());
				} else {
					((MainActivity) context).updateBook(findBookShelfWith(rememberBookItem.rememberShelfName).getBookItemList(),
							findBookShelfWith(rememberBookItem.bookItem.getShelfName()).getBookItemList()
							);
				}
				rememberBookItem = null;
			}
		}
		notifyDataSetChanged();
	}
	
	/////////////////////////////// private ///////////////////////////////////////
	
	/**
	 * Finds all the views we need and configure them to send click events to the activity.
	 *
	 */
	private void setupViews(Context context) 
	{
	    mDragLayer = (DragLayer) ((MainActivity) context).findViewById(R.id.drag_layer);
	    mDragLayer.setDragController(mDragController);
	    mDragController.addDropTarget(mDragLayer);
	}
	
	public boolean startDrag (View v)
	{
	    Object dragInfo = new BookDragInfo( ((BookView) v).getBookItem(), (BookView) v);
	    mDragController.startDrag (v, this, dragInfo, DragController.DRAG_ACTION_MOVE);
	    return true;
	}
	
	private BookShelf findBookShelfWith(String shelfName)
	{
		for(int i=0;i<list.size();i++) {
			BookShelf bookShelf = list.get(i);
			if(bookShelf.getShelfName().equals(shelfName)) {
				return bookShelf;
			}
		}
		return null;
	}
	

	private BookShelfViewHolder newHolder(View convertView)
	{
		BookShelfViewHolder holder = new BookShelfViewHolder();
		holder.hScrollView = (CustomHorizontalScrollView) convertView.findViewById(R.id.hView);
		holder.bookShelfLayout = (CustomLinearLayout) convertView.findViewById(R.id.book_shelf_Layout);
		mDragController.addDropTarget(holder.bookShelfLayout);
		
		holder.shelfNameTextView = (IconTextView) convertView.findViewById(R.id.book_shelf_name_text);
		holder.shelfNameTextView.setOnClickListener(
				new OnClickListener() {
					@Override
					public void onClick(View v) {
						showShelfMenu(((IconTextView)v).getText());
					}
				}
		);
		
		for (int i = 0; i < DEFAULT_BOOK_SIZE_PER_SHELF; i++) {
			if(i==0) {
				holder.bookShelfLayout.addView(new AddBookView(context));
			} else {
				holder.bookShelfLayout.addView(new BookView(context, this));
			}
		}
		return holder;
	}
	
	private void showShelfMenu(final CharSequence text) {
		final AlertDialog.Builder shelfMenuDialog = new AlertDialog.Builder(context);
		shelfMenuDialog.setTitle(context.getString(R.string.shelf_menu));

		shelfMenuDialog.setSingleChoiceItems(R.array.shelf_menus, -1,
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						switch (which) {
						case 0:
							showRenameShelfDlg(text);
							dialog.dismiss();
							break;
						case 1:
							showDeleteShelfDlg(text);
							dialog.dismiss();
							break;
						}
					}
				});
		shelfMenuDialog.show();
	}
	
	private void showRenameShelfDlg(final CharSequence text) {
		final LinearLayout linearLayout = (LinearLayout) View.inflate(context, R.layout.rename_shelf_dlg, null);
		final EditText editText = (EditText) linearLayout.findViewById(R.id.rename_shelf_edit);
		editText.setText(text);
		new AlertDialog.Builder(context)
				.setTitle(R.string.shelf_menu_rename)
				.setView(linearLayout)
				.setNegativeButton(R.string.cancel, null)
				.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
													@Override
													public void onClick(DialogInterface dialog, int which) {
														((MainActivity) context).updateShelfName(text.toString(), editText.getText().toString());
													}
												}
				)
				.show();
		showKeyboard(editText);
	}

	private void showDeleteShelfDlg(final CharSequence text) {
		final LinearLayout linearLayout = (LinearLayout) View.inflate(context, R.layout.delete_shelf_dlg, null);
		final TextView textView = (TextView) linearLayout.findViewById(R.id.delete_shelf_text);
		textView.setText(String.format(context.getString(R.string.shelf_menu_delete_confirm), text));
		new AlertDialog.Builder(context)
				.setTitle(context.getString(R.string.shelf_menu_delete)+"("+text+")")
				.setView(linearLayout)
				.setNegativeButton(R.string.cancel, null)
				.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
													@Override
													public void onClick(DialogInterface dialog, int which) {
														((MainActivity) context).deleteShelf(text.toString());
													}
												}
				)
				.show();
	}
	
	private void showKeyboard(final EditText editText) 
	{
		editText.selectAll();
		editText.requestFocus();
		new Handler().postDelayed(
				new Runnable(){
					public void run(){
						InputMethodManager aaa = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE);
						aaa.showSoftInput(editText,  InputMethodManager.SHOW_IMPLICIT);
					}
				}
				, 100 );
	}

	private void addViewAsMuchAs(int bookCount, BookShelfViewHolder holder)
	{
		int viewCount = holder.bookShelfLayout.getChildCount();
		if(viewCount<=bookCount) {
			int addCount =  (bookCount - viewCount) + 1;
			for(int i=0;i<addCount;i++) {
				holder.bookShelfLayout.addView(new BookView(context, this));
			}
		}
	}
	
	private void initView(BookShelfViewHolder holder, final BookShelf bookShelf)
	{
		for (int i = 0; i < holder.bookShelfLayout.getChildCount(); i++) {
			if(holder.bookShelfLayout.getChildAt(i) instanceof BookView) {
				((BookView) holder.bookShelfLayout.getChildAt(i)).setTag(bookShelf.getShelfName());
				((BookView) holder.bookShelfLayout.getChildAt(i)).setBookItem(null);
				((BookView) holder.bookShelfLayout.getChildAt(i)).setHScrollView(holder.hScrollView);
			}
		}
	}

	private void setupViewWithBookItem(BookShelfViewHolder holder, final int bookCount, final BookShelf bookShelf)
	{
		for (int i = 0,j=0; i < holder.bookShelfLayout.getChildCount(); i++) {
			View view = holder.bookShelfLayout.getChildAt(i);
			if( view instanceof BookView && j < bookCount ) {
				if(!(view instanceof AddBookView)) {
					BookItem bookItem = bookShelf.getBook(j++);
					((BookView) view).setBookItem(bookItem);
				}
			}
		}
	}
}

class BookShelfViewHolder
{
	public int	position;
	public CustomLinearLayout bookShelfLayout;
	public IconTextView shelfNameTextView;
	public CustomHorizontalScrollView hScrollView;
}

class RememberBookItem
{
	public final BookItem bookItem;
	public final int index;
	public final String rememberShelfName;
	
	public RememberBookItem(BookItem bookItem, int index, String rememberShelfName) {
		this.bookItem = bookItem;
		this.index = index;
		this.rememberShelfName = rememberShelfName;
	}
}
